package com.team2.insulatingtools.modular.tools.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription;
import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
import cn.stylefeng.roses.kernel.system.modular.organization.mapper.HrOrganizationMapper;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.team2.insulatingtools.constants.IsMultisection;
import com.team2.insulatingtools.constants.IsWorkshop;
import com.team2.insulatingtools.constants.OrgType;
import com.team2.insulatingtools.constants.ToolsStatus;
import com.team2.insulatingtools.modular.system.entity.ToolsHrOrganization;
import com.team2.insulatingtools.modular.system.mapper.ToolsHrOrganizationMapper;
import com.team2.insulatingtools.modular.tools.dto.QuotaCategoryDto;
import com.team2.insulatingtools.modular.tools.dto.ToolsQuotaDetailDto;
import com.team2.insulatingtools.modular.tools.dto.QuotaDetailDto;
import com.team2.insulatingtools.modular.tools.entity.*;
import com.team2.insulatingtools.modular.tools.mapper.*;
import com.team2.insulatingtools.modular.tools.pojo.request.QuotaRequest;
import com.team2.insulatingtools.modular.tools.pojo.request.ToolsRequest;
import com.team2.insulatingtools.modular.tools.service.CategoryService;
import com.team2.insulatingtools.modular.tools.service.QuotaService;
import com.team2.insulatingtools.modular.tools.service.ToolDetailService;
import com.team2.insulatingtools.modular.tools.service.ToolsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 定额 业务实现层
 *
 * @author team2
 * @date 2023/04/03 09:48
 */
@Service
public class QuotaServiceImpl extends ServiceImpl<QuotaMapper, Quota> implements QuotaService {

    @Resource
    private QuotaMapper quotaMapper;

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private ToolsHrOrganizationMapper toolsHrOrganizationMapper;

    @Resource
    private ToolsMapper toolsMapper;

    @Resource
    private ToolDetailMapper toolDetailMapper;

    @Resource
    private QuotaLogMapper quotaLogMapper;

    @Resource
    private ToolsService toolsService;

    @Resource
    private ToolDetailService toolDetailService;

    @Resource
    private CategoryService categoryService;

    @Override
    public ResponseData selOptionalOrg() {
        // 获取当前登录用户所在的机构
        Long org_id = LoginContext.me().getLoginUser().getOrganizationId();
        QueryWrapper<ToolsHrOrganization> queryWrapper = new QueryWrapper<ToolsHrOrganization>()
                .eq("org_id", org_id).eq("del_flag", "N");
        ToolsHrOrganization hrOrganization = toolsHrOrganizationMapper.selectOne(queryWrapper);
        if (hrOrganization != null){
            // 如果所在机构是检修车间，可操作所在专业下的所有班组
            if (hrOrganization.getIsWorkshop() == IsWorkshop.是.getValue()){
                String[] orgPids = hrOrganization.getOrgPids().split(",");
                ToolsHrOrganization workshop = null;
                // 先向上查找所属专业
                for (String orgPid : orgPids) {
                    QueryWrapper<ToolsHrOrganization> wrapper = new QueryWrapper<ToolsHrOrganization>()
                        .eq("org_id", orgPid.substring(1, orgPid.length()-1))
                            .eq("del_flag", "N")
                            .eq("org_type", OrgType.科室);
                    if (toolsHrOrganizationMapper.selectOne(wrapper) != null){
                        workshop = toolsHrOrganizationMapper.selectOne(wrapper);
                    }
                    break;
                }
                // 然后向下查找专业下的班组
                assert workshop != null;
                QueryWrapper<ToolsHrOrganization> wrapper2 = new QueryWrapper<ToolsHrOrganization>()
                        .like("org_pids", "[" + workshop.getOrgId() + "]")
                        .eq("del_flag", "N")
                        .eq("org_type", OrgType.班组.getValue());
                return new SuccessResponseData(toolsHrOrganizationMapper.selectList(wrapper2));

            } else if (hrOrganization.getOrgType().equals(OrgType.班组.getValue())){
                // 判断当前登录用户的角色是否是班组角色
                // 如果是班组，则只能操作所在班组
                return new SuccessResponseData(hrOrganization);

            } else {
                // 如果既不是班组也不是检修车间，可操作管辖下的班组
                QueryWrapper<ToolsHrOrganization> wrapper3 = new QueryWrapper<ToolsHrOrganization>()
                        .like("org_pids", "[" + hrOrganization.getOrgId() + "]")
                        .eq("del_flag", "N")
                        .eq("org_type", OrgType.班组.getValue());
                return new SuccessResponseData(toolsHrOrganizationMapper.selectList(wrapper3));
            }

        }
        return new ErrorResponseData("10000", "查询可操作班组信息失败！");
    }

    @Override
    public ResponseData selOptionalTool(String org_id) {
        // 获取已有的工具类型
        List<Quota> hasQuotas = quotaMapper.selectList(new QueryWrapper<Quota>().eq("org_id", org_id));
        // 获取全部的工具
        List<Category> categories = categoryMapper.selectList(null);

        // 从查询的列表中，获取已有的工具id
        List<Integer> hastoolCategorys = new ArrayList<>();
        for (Quota quota : hasQuotas) {
            hastoolCategorys.add(quota.getCategoryId());
        }

        categories.removeIf(category -> hastoolCategorys.contains(category.getId()));

        return new SuccessResponseData(categories);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData add(QuotaRequest quotaRequest) {
        if (quotaRequest != null && quotaRequest.getCount() > 0 ){
            // 获取机构信息
            ToolsHrOrganization hrOrganization = toolsHrOrganizationMapper.selectOne(new QueryWrapper<ToolsHrOrganization>()
                    .eq("org_id", quotaRequest.getOrgId()));
            // 机构信息不为空且为班组，才可以添加
            if (hrOrganization != null && hrOrganization.getOrgType().equals(OrgType.班组.getValue())){
                // 判断这类绝缘工具是否存在
                Category category = categoryMapper.selectOne(new QueryWrapper<Category>().eq("name", quotaRequest.getCategory()));
                // 如果绝缘工具表中存在这类工具，可以添加
                if (category != null){
                    // 再次判断该班组是否已有这种绝缘工具
                    QueryWrapper<Quota> wrapper = new QueryWrapper<Quota>()
                            .eq("org_id", quotaRequest.getOrgId())
                            .eq("category_id", category.getId());
                    // 班组没有这类工具，则可以添加该工具
                    if (quotaMapper.selectOne(wrapper) == null){
                        Quota quota = new Quota();
                        quota.setCategoryId(category.getId());
                        BeanUtil.copyProperties(quotaRequest, quota);
                        if (quotaMapper.insert(quota) > 0){
                            this.addBatch(quotaRequest,quota.getId());
                            return addLog(quota.getId(),quotaRequest.getCount());
                        }
                    }
                }
            }
        }
        return new ErrorResponseData("10000", "新增定额数据失败");
    }

    private ResponseData addLog(Integer quotaId,Integer count){
        // 添加操作的历史记录
        String user = LoginContext.me().getLoginUser().getSimpleUserInfo().getRealName();
        QuotaLog quotaLog = new QuotaLog(quotaId, count, user, new Date());
        if (quotaLogMapper.insert(quotaLog) > 0){
            return new SuccessResponseData();
        }
        return new ErrorResponseData("10000", "新增定额数据失败");
    }


    @Override
    public ResponseData selTeamQuota(String org_id) {
        if (StringUtils.hasLength(org_id)){
            return new SuccessResponseData(quotaMapper.selQuotaByOrgId(org_id));
        }
        return new ErrorResponseData("10000", "查询班组已有的绝缘工具失败");
    }

    @Override
    public ResponseData selAllQuota() {
        // 获取当前登录用户所在机构
        String org_id = LoginContext.me().getLoginUser().getOrganizationId() + "";
        ToolsHrOrganization hrOrganization = toolsHrOrganizationMapper.selectOne(
                new QueryWrapper<ToolsHrOrganization>().eq("org_id", org_id));
        if (hrOrganization != null){
            // 如果当前登录用户所在机构属于检修车间,
            // 能够查看本专业下所有班组的信息
            if (hrOrganization.getIsWorkshop() == IsWorkshop.是.getValue()){
                String[] orgPids = hrOrganization.getOrgPids().split(",");
                ToolsHrOrganization workshop = null;
                // 先向上查找所属专业
                for (String orgPid : orgPids) {
                    QueryWrapper<ToolsHrOrganization> queryWrapper = new QueryWrapper<ToolsHrOrganization>()
                            .eq("org_id", orgPid.substring(1, orgPid.length()-1))
                            .eq("del_flag", "N")
                            .eq("org_type", OrgType.科室);
                    if (toolsHrOrganizationMapper.selectOne(queryWrapper) != null){
                        workshop = toolsHrOrganizationMapper.selectOne(queryWrapper);
                    }
                    break;
                }
                assert workshop != null;
                return new SuccessResponseData(quotaMapper.allQuota(workshop.getOrgId()+""));
            }

            // 若当前登录用户所属机构为普通班组，则只能查看所在班组的定额信息
            else if (hrOrganization.getOrgType().equals(OrgType.班组.getValue())
                    && hrOrganization.getIsWorkshop()== IsWorkshop.否.getValue()){
                return new SuccessResponseData(quotaMapper.selQuotaByOrgId(org_id));

            } else {
                // 若当前登录用户所属机构为科室或者车间，则能够查看管辖内所有班组的定额信息
                return new SuccessResponseData(quotaMapper.allQuota(org_id));
            }
        }
        return new ErrorResponseData("10000", "定额数据列表显示失败");
    }

    @Override
    public ResponseData del(int id) {
        List<Tools> tools = toolsMapper.selectList(new QueryWrapper<Tools>().eq("quota_id", id));

        if (tools.size() == 0){
            // 直接删除t_quota定额信息
            if (quotaMapper.deleteById(id) > 0){
                return new SuccessResponseData();
            }

        } else {

            // 状态 0正常/1下架/2报废
            for (Tools tool : tools) {
                if (tool.getStatus() == 0 && tool.getKeeper() != null){
                    //有保管人且状态正常，就不能删除定额信息  （旧版本只要存在正常状态的定额工具）
                    return new ErrorResponseData("10000", "工具正在使用中");
                }
            }

            // 如果分节，就先删除 t_tool_detail表中的数据
            for (Tools tool : tools) {
                if (tool.getIsMultisection().equals(IsMultisection.分节.getValue())){
                    QueryWrapper<ToolDetail> queryWrapper = new QueryWrapper<ToolDetail>().eq("tool_id", tool.getId());
                    int delResult = toolDetailMapper.delete(queryWrapper);
                    if (delResult <= 0){
                        // 任意一个没有删除成功就会删除失败
                        return new ErrorResponseData("10000", "工具详情表信息删除失败");
                    }
                }
            }

            // 删除t_tools表中的数据
            if (toolsMapper.delete(new QueryWrapper<Tools>().eq("quota_id", id)) > 0){
                // 删除t_quota定额信息
                if (quotaMapper.deleteById(id) > 0){
                    return new SuccessResponseData();
                }
            }
        }

        return new ErrorResponseData("10000", "删除定额数据失败");
    }

    @Override
    public ResponseData selQuotaLog(String quotaId) {
        QueryWrapper<QuotaLog> queryWrapper = new QueryWrapper<QuotaLog>().eq("quota_id", quotaId);
        return new SuccessResponseData(quotaLogMapper.selectList(queryWrapper));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addQuota(QuotaRequest quotaRequest) {
        Quota quota = this.getById(quotaRequest.getId());
        if (quota.getCount() < quotaRequest.getCount()){
            quota.setCount(quotaRequest.getCount());
            this.updateById(quota);
        }else{
            throw new RuntimeException("新增数量异常");
        }
        this.addBatch(quotaRequest,quota.getId());
        this.addLog(quota.getId(),quotaRequest.getCount());
    }

    private void addBatch(QuotaRequest quotaRequest,Integer quotaId){
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        categoryQueryWrapper.eq("name", quotaRequest.getCategory());
        Category category = categoryService.getOne(categoryQueryWrapper);
        ToolsRequest toolsRequest = new ToolsRequest();
        toolsRequest.setSpeciality(quotaRequest.getSpeciality());
        toolsRequest.setQuotaId(quotaId);
        toolsRequest.setStatus(ToolsStatus.正常.getValue());
        toolsRequest.setName(quotaRequest.getCategory());
        toolsRequest.setWorkingVoltage(category.getWorkingVoltage());
        toolsRequest.setLength(category.getLength());
        toolsRequest.setLastingTime(category.getTestDuration());
        toolsRequest.setCycle(category.getTestPeriod());
        toolsRequest.setUnit(category.getUnit());
        toolsService.addBatch(toolsRequest,quotaRequest.getCount());
    }

    @Override
    public List<ToolsQuotaDetailDto> selectToolQuotaList(Long orgId,Integer quotaId) {
        return quotaMapper.selectToolQuotaList(orgId,quotaId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteTools(QuotaRequest quotaRequest){
        int size = quotaRequest.getToolIdList().size();
        Quota quota = this.getById(quotaRequest.getId());
        int realChangeNum = quota.getCount() - quotaRequest.getCount();
        if (size != realChangeNum){
            throw new RuntimeException("删除的数量与定额减少数量不一致");
        }
        toolsService.deleteBatchByToolIdList(quotaRequest.getToolIdList());
        toolDetailService.deleteBatchByToolIdList(quotaRequest.getToolIdList());
        quota.setCount(quotaRequest.getCount());
        this.updateById(quota);
        this.addLog(quota.getId(),quotaRequest.getCount());
    }



    /**
     * 查询车间或班组的定额信息
     * @param orgId
     * @return
     */
    @Override
    public ResponseData selWorkshopOrTeamQuota(String orgId) {
        if (StringUtils.hasLength(orgId)){
            // 获取当前组织机构
            ToolsHrOrganization hrOrganization = toolsHrOrganizationMapper.selectOne(
                    new QueryWrapper<ToolsHrOrganization>().eq("org_id", orgId));
            // 如果是班组，仅获取当前班组信息
            if (hrOrganization.getOrgType().equals(OrgType.班组.getValue())){
                return new SuccessResponseData(quotaMapper.selQuotaByOrgId(orgId));
            }
            // 如果是车间，可获取本车间管辖下班组的定额信息
            if (hrOrganization.getOrgType().equals(OrgType.车间.getValue())){
                List<ToolsHrOrganization> orgs =
                        toolsHrOrganizationMapper.selectList(new QueryWrapper<ToolsHrOrganization>().eq("org_parent_id", orgId));
                if (orgs.size() > 0){
                    List<QuotaDetailDto> quotaDetailDtos = new ArrayList<>();
                    for (ToolsHrOrganization org : orgs) {
                        List<QuotaDetailDto> list = quotaMapper.selQuotaByOrgId(org.getOrgId() + "");
                        if (list.size() > 0){
                            quotaDetailDtos.addAll(list);
                        }
                    }
                    return new SuccessResponseData(quotaDetailDtos);
                }
            }
        } else {
            return this.selAllQuota();
        }

        return new ErrorResponseData("10000", "查询车间或班组的定额数据失败");
    }




}
